/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import entities.exceptions.CrossingOccupiedException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import javax.swing.border.LineBorder;
import willispace.Config;
import willispace.Log;

/**
 *
 * @author mateusz
 */
public class Tile extends MyPanel {

    private Crossing crossing;
    private Boolean blocked;
    private Entity associatedEntity; // zasób albo fabryka
    private int tileX, tileY;
    private volatile int onRoute; // na ilu drogach jest pole

    /**
     * Creates new tile
     * @param position  position
     * @param blocked   if tile is blocked
     * @param bg        background image
     */
    public Tile(Point position, Boolean blocked, Image bg) {
        this(position, blocked, bg, null);
    }

    /**
     * Creates new tile
     * @param position  position
     * @param blocked   if tile is blocked
     * @param bg        background image
     * @param associatedEntity entity associated
     */
    public Tile(Point position, Boolean blocked, Image bg, Entity associatedEntity) {
        super(position, bg);
        tileX = position.x;
        tileY = position.y;

        onRoute = 0;

        setBorder(new LineBorder(Color.white));
        crossing = new Crossing();
        this.blocked = blocked;

        associateWithEntity(associatedEntity);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, null);
    }

    /**
     * 
     * @return indexes of tile on map
     */
    public Point getIndexes() {
        return new Point(tileX, tileY);
    }

    /**
     * 
     * @return position of left-top corner of tile (global)
     */
    public Point getXY() {
        return new Point(tileX * Config.tileWidth, tileY * Config.tileHeight);
    }

    /**
     * block this tile
     */
    public void block() {
        //Log.l("Blokuję płytkę " + this.toString());
        this.blocked = true;
    }

    /**
     * 
     * @return true if tile is blocked
     */
    public Boolean isBlocked() {
        return this.blocked;
    }

    /**
     * associates this tile with some entity
     * block this tile
     * @param e entity
     */
    public void associateWithEntity(Entity e) {
        this.associatedEntity = e;

        if (e != null) {
            this.blocked = true;
            crossing.setUnlimited();
        }
    }

    /**
     * 
     * @return associated entity
     */
    public Entity getAssociatedEntity() {
        return associatedEntity;
    }

    /**
     * unassociate with entity
     * set blocked to false
     * set limited crossing
     */
    public void unassociateWithEntity() {
        this.associatedEntity = null;
        this.blocked = false;
        setLimited();
    }

    /**
     * occupy crossing
     * @param r robot
     * @throws CrossingOccupiedException    if crossing can't be taken
     */
    public void occupy(Robot r) throws CrossingOccupiedException {
        crossing.occupy(r);
    }

    /**
     * unoccupy crossing
     * @param r robot
     */
    public void unoccupy(Robot r) {
        crossing.unoccupy(r);
    }

    /**
     * tell crosing that robot is going out
     * @param r robot
     */
    public void goingOut(Robot r) {
        crossing.goingOut(r);
    }

    /**
     * 
     * @return true if tile is on any route
     */
    public synchronized boolean isOnRoute() {
        return onRoute > 0;
    }

    /**
     * increases onRoute counter
     */
    public synchronized void increaseRoutes() {
        this.onRoute++;
    }

    /**
     * decreases onRoute counter
     */
    public synchronized void decreaseRoutes() {
        this.onRoute--;
    }

    /**
     * set crossing to unlimited
     */
    public void setUnlimited() {
        crossing.setUnlimited();
    }

    /**
     * set crossing to limited
     */
    public void setLimited() {
        crossing.setLimited();
    }

    @Override
    public String toString() {
        return "Tile[" + this.getIndexes().y + "][" + this.getIndexes().x + "]";
    }
}
